import { isFunction } from "@/utils";
import { DataTableBaseColumn } from "naive-ui";
import { defaultRender } from "../helpers/renders";
import {
  ZTableMethods,
  WritablePaginationProps,
  ZTableColumn,
} from "../typings";
import { ZTableProps } from "../ZTable.vue";

export const INDEX_COLUMN_KEY = "$index$";
export const INDEX_COLUMN_TITLE = "序号";
export const ACTION_COLUMN_KEY = "$action$";
export const ACTION_COLUMN_TITLE = "操作";

export function useColumns(
  props: ZTableProps,
  pagination: WritablePaginationProps | false,
  methods: ZTableMethods
) {
  const { columns } = props.tableProps;

  if (
    props.indexColumn &&
    columns.every(
      (col) => (col as DataTableBaseColumn)?.key !== INDEX_COLUMN_KEY
    )
  ) {
    const indexColumn: ZTableColumn = {
      key: INDEX_COLUMN_KEY,
      title: props.indexColumnTitle ?? INDEX_COLUMN_TITLE,
      render({ rowIndex }) {
        const index = rowIndex + (props.indexColumnOffset ?? 0);
        if (
          pagination &&
          pagination.page &&
          pagination.pageSize &&
          props.indexColumnIncreaseWithPage
        ) {
          return index + (pagination.page - 1) * pagination.pageSize;
        }
        return index;
      },
    };
    // index column will be the first column.
    columns.unshift(indexColumn);
  }

  if (
    props.actionColumn &&
    columns.every(
      (col) => (col as DataTableBaseColumn)?.key !== ACTION_COLUMN_KEY
    )
  ) {
    const actionColumn: ZTableColumn = {
      key: ACTION_COLUMN_KEY,
      title: ACTION_COLUMN_TITLE,
      ...props.actionColumn,
    };
    // action column will be the last column.
    columns.push(actionColumn);
  }

  return enhanceColumnsRender(columns, methods);
}

/**
 * mix ${tableMethods} into render.
 * `render({ rowData, rowIndex, methods })`
 */
export function enhanceColumnsRender(
  columns: ZTableColumn[],
  methods: ZTableMethods
) {
  return columns.map<DataTableBaseColumn>((column) => {
    const { render, ...rest } = column;
    return {
      ...rest,
      render(rowData, rowIndex) {
        return isFunction(render)
          ? render({ rowData, rowIndex, ...rest, methods })
          : defaultRender({ rowData, rowIndex, ...rest, methods });
      },
    };
  });
}
